﻿
package com.ostrich.manpower.service.impl;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.poi.ss.formula.ptg.TblPtg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.base.service.BaseService;
import com.ostrich.manpower.bean.TostHrBaseinfo;
import com.ostrich.manpower.bean.TostHrDepartinfo;
import com.ostrich.manpower.bean.TostHrFactpayinfo;
import com.ostrich.manpower.bean.TostHrSubsidyinfo;
import com.ostrich.manpower.bean.TostHrZhongheinfo;
import com.ostrich.manpower.common.DateUtil;
import com.ostrich.manpower.common.FormulaUtil;
import com.ostrich.manpower.common.WorkDayUtil;
import com.ostrich.manpower.service.TostHrFactpayinfoDao;
import com.ostrich.project.bean.TostPjGeneraltable;
import com.ostrich.project.bean.TostPjNoncashinfo;
import com.ostrich.project.service.impl.TostPjGeneraltableService;
import com.ostrich.project.service.impl.TostPjNoncashinfoService;
import com.ostrich.system.analysis.ParaminfoUtil;
/**
 * @author wangyinan
 * @brief    模块功能简单描述
 * @details  模块功能详细描述
 */
@Service("tostHrFactpayinfoService")
public class TostHrFactpayinfoService<T> extends BaseService<T> {
	private final static Logger log= Logger.getLogger(TostHrFactpayinfoService.class);

	@Autowired
    private TostHrFactpayinfoDao<T> dao;
	@Autowired(required=false)
	private TostHrBaseinfoService<TostHrBaseinfo> tostHrBaseinfoService;
	
	@Autowired(required=false)
	private TostHrDepartinfoService<TostHrDepartinfo> tosthrdepartinfoservice;
	
	@Autowired(required=false)
	private TostPjNoncashinfoService<TostPjNoncashinfo> tostpjnoncashinfoservice;
	
	@Autowired(required=false)
	private TostPjGeneraltableService<TostPjGeneraltable> tostpjgeneraltableservice;
	
	@Autowired(required=false)
	private TostHrSubsidyinfoService<TostHrSubsidyinfo> tosthrsubsidyinfoservice;
	
	@Autowired(required=false)
	private TostHrZhongheinfoService<TostHrZhongheinfo> tosthrzhongheinfoservice;
	
	
	public TostHrFactpayinfoDao<T> getDao() {
		return dao;
	}
	
	public List<T> queryByHrid(Integer hrid) {
		return getDao().queryByHrid(hrid);
	}

	public void deleteByhrMonth(String hrMonth,int hrId){
		dao.deleteByhrMonth(hrMonth,hrId);
	}
	
	public List<T> queryByHrMonthHrid(String hmeMonth,int hrId){
		return dao.queryByHrMonthHrid(hmeMonth, hrId);
	}
	
	/****
	 * 添加应付表对应信息
	 * @param hmeMonth
	 * @param bsinfo
	 * @return
	 * @throws Exception
	 */
	public TostHrFactpayinfo addFactpay(String hmeMonth,TostHrBaseinfo bsinfo) throws Exception{
		
		TostHrFactpayinfo tsl=new TostHrFactpayinfo();
		DecimalFormat df2  = new DecimalFormat("###.00");
		//如果离职的月份不是计算工资的月份就不用计算
		if ( bsinfo.getHrQuittime()!=null && bsinfo.getHrQuittime().length() > 1 && (!DateUtil.getYearMonthByDate(bsinfo.getHrQuittime()).equals(hmeMonth))) {
			return tsl;
		}
		else {
				int nowMonthWorkDay = 0;
				
				tsl.setHrId(bsinfo.getId());
				tsl.setHfaMonth(hmeMonth);
				
				List<TostHrFactpayinfo> lst=(List<TostHrFactpayinfo>) dao.queryByHrMonthHrid(hmeMonth,bsinfo.getId());
				
				//执行工资
				Float jxgz = bsinfo.getHrExesalry()!=null?bsinfo.getHrExesalry():new Float(0);
				//提留工资
				Float tlgz = bsinfo.getHrLeavemoney()!=null?bsinfo.getHrLeavemoney():new Float(0);
				//基本工资=执行工资-提留工资
				Float jiben = jxgz-tlgz;
				
				//查询工资综合表
				TostHrZhongheinfo thz = tosthrzhongheinfoservice.queryZhongheByhrid(bsinfo.getId(),hmeMonth);
				//绩效工资 =基础表的绩效工资*工资综合表里的系数    工资综合表里的系数为null 默认为1
				if(thz==null){
					thz = new TostHrZhongheinfo();
					thz.setHzhCoefficient(new Float(0));
					thz.setHzhPushmoney(new Float(0));
					thz.setHzhBackpay(new Float(0));
				}
				
				//基础表的绩效工资
				Float jcjxgz = bsinfo.getHrPushmoney()!=null?bsinfo.getHrPushmoney():new Float(0);
				//绩效工资 =基础表的绩效工资*工资综合表里的系数    工资综合表里的系数为null 默认为1
				Float jx = thz.getHzhCoefficient()!=null?(jcjxgz*thz.getHzhCoefficient()):jcjxgz;
				//从工资综合表 来的提成工资
				Float tc = thz.getHzhPushmoney()!=null?thz.getHzhPushmoney():new Float(0.0);
				
				
				//离职
				if ( bsinfo.getHrQuittime()!=null && bsinfo.getHrQuittime().length() > 0  ) {
					//结算工资的月份等于离职月份
					if (DateUtil.getYearMonthByDate(bsinfo.getHrQuittime()).equals(hmeMonth)) {
						//转正时间
						String positivetime = bsinfo.getHrPositivetime();
						
						//结算工资的年
						String l_nowYear = hmeMonth.substring(0,4);
						//结算工资的月
						String l_nowMonth = hmeMonth.substring(4,6);
						//结算的月份的工作日
						int l_nowMonthWorkDay = this.getNowMonthWorkDay(l_nowYear, l_nowMonth);
						//离职的时间
						String l_quittime = bsinfo.getHrQuittime();
						//离职的年
						String l_quitYear = l_quittime.substring(0,4);
						//离职的月
						String l_quitMonth = l_quittime.substring(5,7);
						//离职的号数
						String l_quitDay = l_quittime.substring(8,10);
						//到离职时间前的工作日
						int l_quitWorkDay = WorkDayUtil.showTime(l_quitYear+"-"+l_quitMonth+"-01", l_quitYear+"-"+l_quitMonth+"-"+l_quitDay);
						//比率
						float l_q_n = (float)l_quitWorkDay/l_nowMonthWorkDay;
						float f_l_q_n = Float.parseFloat(df2.format(l_q_n));
						//基本工资=(执行工资标准-提留工资)*80%*(试用期天数/当月工作日天数)
						//试用期离职（转正时间为空）
						if ( "".equals(positivetime) ){
							System.out.println("试用期离职");
							//判断是否是试用期，试用期，基本工资，绩效工资,提成工资都 乘以80%。
							jiben = jiben*new Float(0.8) * f_l_q_n;
							jx = jx*new Float(0.8) * f_l_q_n;
							tc = tc*new Float(0.8) * f_l_q_n;
						}//正式在职时离职(转正时间为空不为空)
						else if (positivetime != null && (DateUtil.getYearMonthByDate(positivetime).equals(hmeMonth))){
							System.out.println("试用期和转正的时候离职");
							//转正的时间
							String l_positiveTime = bsinfo.getHrPositivetime();
							//试用期的工作日天数
							int l_probationWorkDay = WorkDayUtil.showTime(l_quitYear+"-"+l_quitMonth+"-01", l_positiveTime);
							//正式在职的工作日天数   
							int l_inSvrviceWorkDay = WorkDayUtil.showTime(l_positiveTime, bsinfo.getHrQuittime());
							//试用期工作日天数/当前月工作日天数
							float l_p_q = (float)l_probationWorkDay/l_nowMonthWorkDay;
							float f_l_p_q = Float.parseFloat(df2.format(l_p_q));
							//转正工作天数/当前月工作日天数
							float l_i_q = (float)l_inSvrviceWorkDay/l_nowMonthWorkDay;
							float f_l_i_q = Float.parseFloat(df2.format(l_i_q));
							//基本工资=(执行工资标准-提留工资)*80%*(试用期天数工作日/当月工作日)+（执行工资标准-提留工资）*(转正天数工作日/当月工作日)
							jiben = (jxgz-tlgz)*new Float(0.8)*f_l_p_q + (jxgz-tlgz)*f_l_i_q;
							jx = jx*new Float(0.8)*f_l_p_q + jx*f_l_i_q;
							tc = tc*new Float(0.8)*f_l_p_q + tc*f_l_i_q;
							
						}//试用期和转正的时候离职
						else  {
							jiben = jiben * f_l_q_n;
							jx = jx* f_l_q_n;
							tc = tc * f_l_q_n;
						}
						
					}
					
					
				}//未离职
				else {
					//转正时间为生成年月。HR_POSITIVETIME
					String conversionTime = bsinfo.getHrPositivetime();
					//判断是否是试用期，试用期，基本工资，绩效工资,提成工资都 乘以80%。
					
					if(bsinfo.getHrGrades()!=null && bsinfo.getHrGrades().equals("12") && conversionTime.length() == 0 ){
						jiben = jiben*new Float(0.8);
						jx = jx*new Float(0.8);
						tc = tc*new Float(0.8);
					}
					System.out.println(conversionTime.length());
					//在试用期转正时的工资算法
					if(conversionTime.length() > 0  && bsinfo.getHrGrades()!=null && bsinfo.getHrGrades().equalsIgnoreCase("13")) {
						 if (DateUtil.getYearMonthByDate(conversionTime).equals(hmeMonth)) {
							String nowYear = hmeMonth.substring(0,4);
							String nowMonth = hmeMonth.substring(4,6);
							//计算当前月的工作日
							nowMonthWorkDay = this.getNowMonthWorkDay(nowYear, nowMonth);
							//试用期天数
								int probationDay = WorkDayUtil.showTime(nowYear+"-"+nowMonth+"-01", conversionTime);
							//正式在职的天数
								int workDay = nowMonthWorkDay - probationDay;
								//基本工资=(执行工资标准-提留工资)*80%*(试用期天数/当月工作日天数)+（执行工资标准-提留工资）*(转正天数/当月工作日天数)  注：转正天数+试用期天数=当月工作日天数
								float p_nowD = (float)probationDay/nowMonthWorkDay;
								float f_p_nowD = Float.parseFloat(df2.format(p_nowD));
								
								float w_nowD = (float)workDay/nowMonthWorkDay;
								float f_w_nowD = Float.parseFloat(df2.format(w_nowD));
								
								jiben = (jxgz-tlgz)*new Float(0.8)*f_p_nowD + (jxgz-tlgz)*f_w_nowD;
								jx = jx*new Float(0.8)*f_p_nowD + jx*f_w_nowD;
								tc = tc*new Float(0.8)*f_p_nowD + tc*f_w_nowD;
							}
					}
					
				}
				
				//为基本工资和绩效工资和提成工资设值。
				tsl.setHfaBassalary(jiben);
				tsl.setHfaMeritPay(jx);
				tsl.setHfaCommissionwag(tc);
				//补发工资
				tsl.setHfaReplacement(thz.getHzhBackpay()!=null?thz.getHzhBackpay():new Float(0.0));
				//工龄工资
				tsl.setHfaSenioritypay(workAges(bsinfo));
				//福利费
				tsl.setHfaWelfarism(Welfar(hmeMonth));
				//应发工资:　基本工资+绩效+提成+工龄工资+补发
				Float yingfa = tsl.getHfaBassalary()+tsl.getHfaMeritPay()+tsl.getHfaCommissionwag()+tsl.getHfaSenioritypay()+tsl.getHfaReplacement();
				tsl.setHfaCount(yingfa);
				
				
				if(lst!=null && lst.size()>0){
					tsl.setId(lst.get(0).getId());
					dao.update((T) tsl);
				}else
					dao.add((T) tsl);
				return tsl;
				}
	}
	
	/***
	 * 计算福利所得信息
	 * @param hmeMonth
	 * @return
	 */
		private Float Welfar(String hmeMonth){
		if(hmeMonth.length()>=6){
			//季节补贴费用
			float heat=Float.parseFloat(ParaminfoUtil.getPminfoById(131).getPaValue());
			float down=Float.parseFloat(ParaminfoUtil.getPminfoById(132).getPaValue());

			String temple=String.valueOf(hmeMonth);
			temple=temple.substring(4,temple.length());
			if(temple.equals("07") || temple.equals("08") || temple.equals("09")){
				return heat;				
			}else if(temple.equals("10") || temple.equals("11") || temple.equals("12")){
				return down;
			}
		}
		return new Float(0);
	}
		
	/***
	 * 计算的工龄工资
	 * @param bsinfo
	 * @return
	 * @throws ParseException
	 */
	private Float workAges(TostHrBaseinfo bsinfo) throws ParseException{
		long now=(new Date().getTime())/1000/60/60/24;
		if(bsinfo.getHrPositivetime()!=null && bsinfo.getHrPositivetime().trim().length()>0){
			Date hrposttime = DateUtil.ShortstringToDate(bsinfo.getHrPositivetime());
			long zz=(hrposttime.getTime())/1000/60/60/24;
			long gn=(now-zz)/365;
			if(gn>0){
				float gngz=(float) gn*100;
				return gngz;//工龄工资！
			}
		}
		return new Float(0);
	}
	
	//??????提成工资
	public TostHrFactpayinfo addFactpayinfo(int hmeMonth,int hrId) throws Exception{
		
		TostHrFactpayinfo thfi=new TostHrFactpayinfo();
		thfi.setHrId(hrId);
		TostHrBaseinfo thb=tostHrBaseinfoService.queryById(hrId);
		float hj=0;
		//for(TostHrBaseinfo thb:baselist){
		if(thb==null || thb.getId()==null)
			return null;
		
			float zx=(thb.getHrExesalry()==null)?0:thb.getHrExesalry();//空指针异常
			float tl=(thb.getHrLeavemoney()==null)?0:thb.getHrLeavemoney();
			float jb=zx-tl;//基本工资=执行工资-提留工资。
			hj+=jb;
			thfi.setHfaBassalary(jb);//基本工资
			try {
				long now=(new Date().getTime())/1000/60/60/24;
				long zz=(new SimpleDateFormat("yyyy-MM-dd").parse(thb.getHrPositivetime()).getTime())/1000/60/60/24;
				int gn=(int)((now-zz)/365);
				if(gn>0){
					float gngz=(float) gn*100;
					hj+=gngz;
					thfi.setHfaSenioritypay(gngz);//工龄工资！
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}
		//}
		thfi.setHfaCommissionwag(null);//??????提成工资
		
		int nowmonth=Calendar.getInstance().get(Calendar.MONTH)+1;
		if(nowmonth==7||nowmonth==8||nowmonth==9){
			float jw=Float.parseFloat(ParaminfoUtil.getPminfoById(21).getPaValue());
			hj+=jw;
			thfi.setHfaWelfarism(jw);
		}
		if(nowmonth==10||nowmonth==11||nowmonth==12){
			float qn=Float.parseFloat(ParaminfoUtil.getPminfoById(22).getPaValue());
			hj+=qn;
			thfi.setHfaWelfarism(qn);
		}
		thfi.setHfaReplacement((float)0.0);//补发工资。
		thfi.setHfaCount(hj);
		thfi.setHfaMonth(Integer.toString(hmeMonth));
		
		this.add((T) thfi);
		
		return thfi;
	}
	
	/****
	 * 实现提成、绩效的计算方法
	 * @param hmeMonth
	 * @param thb
	 * @return
	 * @throws Exception 
	 */
	
	//提成工资算法，不用了。
	private Float generatePushmoney(String hmeMonth,TostHrBaseinfo thb) throws Exception{
		//判断这个部门是什么类型部门，是绩效的部门还是提成的部门
		if(thb.getHrDepart()!=null){
			TostHrDepartinfo dpart = tosthrdepartinfoservice.queryById(thb.getHrDepart());
			
			if(dpart==null || dpart.getId()==null){
				return new Float(0);
			}
			if(dpart!=null && "1".equals(dpart.getHdpStatus())) //表示部门的状态被冻结，如果冻结，人员工资也被冻结为0
					return new Float(0);
			//判断部门属于什么类型绩效、还是提成  0绩效1提成  HDP_TYPE 参数表的 36为绩效类型 37为提成类型
			if(dpart.getHdpType().equals("36")){
//				TostPjNoncashinfo pjnon = new TostPjNoncashinfo();
//				int jobty = (StringUtils.isNum(thb.getHrJobs()))?Integer.parseInt(thb.getHrJobs()):0;
//				pjnon.setHpoId(jobty);
//				int pty = (StringUtils.isNum(thb.getHrLevel()))?Integer.parseInt(thb.getHrLevel()):0;
//				pjnon.setPncType(pty);//级别
//				//为项目的绩效算法，在noncashinfo 表中有个对应数据信息
//				List<TostPjNoncashinfo> ls = tostpjnoncashinfoservice.queryByList(pjnon);
//				if(ls!=null && ls.size()>0)
//					pjnon = ls.get(0);
//				
//				return pjnon.getPncDepmanager()!=null?pjnon.getPncDepmanager():new Float(0);//返回绩效查询内容  默认系数为1
				Map<String,Object> mulnum = FormulaUtil.formulaById(2, thb.getHrExesalry(),new Float(1));
				return (Float)mulnum.get("mul");
			}else{
				//为项目的提成算法?????
				Map<String,Object>  map =tostpjgeneraltableservice.queryByHrid(thb.getId());// 获取项目中的 编制汇总表 中的非现金支出 按月出费用
				if(map!=null && map.get("pushpay")!=null){
					Double pjpush = (Double)map.get("pushpay");
					return new Float(pjpush);
				}
			}
		}
			
		return new Float(0);
	}
	/**
	 * 返回年某月的工作日天数
	 * @param nowYear
	 * @param nowMonth
	 * @return
	 */
	public int getNowMonthWorkDay(String nowYear,String nowMonth){
		int intNowYear = Integer.parseInt(nowYear);
		int nowMonthWorkDay = 0;
		switch (Integer.parseInt(nowMonth)) {
		//大月
		case 1:case 3:case 5:case 7:case 8:case 10:case 12:
			nowMonthWorkDay = WorkDayUtil.showTime(nowYear+"-"+nowMonth+"-01", nowYear+"-"+nowMonth+"-31");
			break;
		//小月
		case 4:case 6:case 9:case 11:
			nowMonthWorkDay = WorkDayUtil.showTime(nowYear+"-"+nowMonth+"-01", nowYear+"-"+nowMonth+"-30");
		case 2:
		//判断是否为闰年
			if (intNowYear%4 == 0 && intNowYear%100!=0 || intNowYear%400 == 0) {
				nowMonthWorkDay = WorkDayUtil.showTime(nowYear+"-"+nowMonth+"-01", nowYear+"-"+nowMonth+"-29");
			}
			else 
				nowMonthWorkDay = WorkDayUtil.showTime(nowYear+"-"+nowMonth+"-01", nowYear+"-"+nowMonth+"-28");
			break;
		}
		return nowMonthWorkDay;
	}
}
